#ifndef U2ArchiveFile_H
#define U2ArchiveFile_H

#include "U2PreRequest.h"
#include "U2MemoryAllocatorConfig.h"
#include "U2SharedPtr.h"
#include "U2Archive.h"
#include "U2ArchiveFactory.h"


U2EG_NAMESPACE_BEGIN


class _U2Share U2ArchiveFile : public U2Archive
{
protected:
    /** Utility method to retrieve all files in a directory matching pattern.
    @param pattern File pattern
    @param recursive Whether to cascade down directories
    @param dirs Set to true if you want the directories to be listed
        instead of files
    @param simpleList Populated if retrieving a simple list
    @param detailList Populated if retrieving a detailed list
    @param currentDir The current directory relative to the base of the 
        archive, for file naming
    */
    void findFiles(const U2String& pattern, bool recursive, bool dirs,
        U2StringVector* simpleList, FileInfoList* detailList) const;

	U2_AUTO_MUTEX
public:
    U2ArchiveFile(const U2String& name, const U2String& archType );
    ~U2ArchiveFile();

    /// @copydoc Archive::isCaseSensitive
    bool isCaseSensitive(void) const;

    /// @copydoc Archive::load
    void load();
    /// @copydoc Archive::unload
    void unload();

    /// @copydoc Archive::open
    U2DataStreamPtr open(const U2String& filename, bool readOnly = true) const;

	/// @copydoc Archive::create
	U2DataStreamPtr create(const U2String& filename) const;

	/// @copydoc Archive::delete
	void remove(const U2String& filename) const;

	/// @copydoc Archive::list
    U2StringVectorPtr list(bool recursive = true, bool dirs = false);

    /// @copydoc Archive::listFileInfo
    FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);

    /// @copydoc Archive::find
    U2StringVectorPtr find(const U2String& pattern, bool recursive = true,
        bool dirs = false);

    /// @copydoc Archive::findFileInfo
    FileInfoListPtr findFileInfo(const U2String& pattern, bool recursive = true,
        bool dirs = false) const;

    /// @copydoc Archive::exists
    bool exists(const U2String& filename);

	/// @copydoc Archive::getModifiedTime
	time_t getModifiedTime(const U2String& filename);

	/// Set whether filesystem enumeration will include hidden files or not.
	/// This should be called prior to declaring and/or initializing filesystem
	/// resource locations. The default is true (ignore hidden files).
	static void setIgnoreHidden(bool ignore)
	{
		msIgnoreHidden = ignore;
	}

	/// Get whether hidden files are ignored during filesystem enumeration.
	static bool getIgnoreHidden()
	{
		return msIgnoreHidden;
	}

	static bool msIgnoreHidden;
};



/** Specialisation of ArchiveFactory for FileSystem files. */
//class _OgrePrivate FileSystemArchiveFactory : public ArchiveFactory
class _U2Share U2ArchiveFactoryFile : public U2ArchiveFactory
{
public:
	virtual ~U2ArchiveFactoryFile() {}
	/// @copydoc U2FactoryObj::getType
	const U2String& getType(void) const;
	/// @copydoc U2FactoryObj::createInstance
	U2Archive *createInstance( const U2String& name ) 
	{
		return U2_NEW U2ArchiveFile(name, "FileSystem");
	}
	/// @copydoc U2FactoryObj::destroyInstance
	void destroyInstance(U2Archive* arch) { delete arch; }
};



U2EG_NAMESPACE_END

#endif